package com.example.framework509.codeGen.controller;

import com.example.framework509.codeGen.entity.Entity;
import com.example.framework509.codeGen.entity.EntityFieldMapper;
import com.example.framework509.codeGen.entity.Field;
import com.example.framework509.codeGen.entity.Mapper;
import com.example.framework509.codeGen.entity.middlePojp.EntityContainer;
import com.example.framework509.codeGen.mapper.EntityMapper;
import com.example.framework509.codeGen.service.impl.CodeGenServiceImpl;
import com.example.framework509.codeGen.service.impl.EntityServiceImpl;
import com.example.framework509.codeGen.service.impl.SqlServiceImpl;
import com.example.framework509.codeGen.utils.SqlUtil;
import com.example.framework509.common.annotation.AutoEntityProcess;
import com.example.framework509.common.annotation.AutoMapperProcess;
import com.example.framework509.common.annotation.AutoRequestBody;
import com.example.framework509.common.entities.ResMsg;
import com.example.framework509.common.exceptions.JdbcException;
import com.example.framework509.common.exceptions.ParamFieldException;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/dbTable")
@CrossOrigin
public class TableController {

    @Autowired
    private CodeGenServiceImpl codeGenService;
    @Autowired
    private EntityServiceImpl entityService;
    @Autowired
    private EntityMapper entityMapper;
    @Autowired
    private SqlUtil sqlUtil;
    @Autowired
    private SqlServiceImpl sqlService;

    @RequestMapping("/entity")
    @AutoEntityProcess(BUSINESS_CLASS = Entity.class, LOG_MSG = "业务实体")
    public ResMsg entity(@AutoRequestBody Map param) {
        return null;
    }

    @RequestMapping("/field")
    @AutoEntityProcess(BUSINESS_CLASS = Field.class, LOG_MSG = "实体字段", PERMISSION_TYPE = "2345", CUSTOM_EXECUTE = true)
    public ResMsg field(@AutoRequestBody Map param, HttpServletRequest request) {
        if (request.getMethod().equals("POST") || request.getMethod().equals("PUT")) {
            if (param.get("dataType").equals("String") && (!param.containsKey("length") || param.get("length") == null))
                throw new ParamFieldException("字符串类型必须指定长度");
        }
        return null;
    }

    @RequestMapping("/entityFieldMapper")
    @AutoMapperProcess(LOG_MSG = "业务实体和字段映射", FOR_ENTITY = true)
    public ResMsg entityFieldMapper(@RequestBody List<EntityFieldMapper> param) {
        return null;
    }

    @RequestMapping("/mapper")
    @AutoEntityProcess(BUSINESS_CLASS = Mapper.class, LOG_MSG = "实体映射", CUSTOM_EXECUTE = true)
    public ResMsg mapper(@AutoRequestBody Map param, HttpServletRequest request) {
        if (request.getMethod().equals("POST")) {
            entityService.getEntityFromId(Integer.parseInt(param.get("primaryEntityId").toString()), false);
            entityService.getEntityFromId(Integer.parseInt(param.get("secondaryEntityId").toString()), false);
        }
        return null;
    }

    @RequestMapping("/gen")
    @AutoEntityProcess(LOG_MSG = "代码生成", CUSTOM_EXECUTE = true, AUTO_EXECUTE = false)
    public void genCode(@RequestParam("mainPath") String mainPath, HttpServletResponse response) throws Exception {
        List<EntityContainer> entitiesInfo = codeGenService.getEntitiesInfo();
        byte[] data = codeGenService.generatorCode(entitiesInfo, mainPath);

        response.reset();
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setHeader("Content-Disposition", "attachment; filename=\"autoCode.zip\"");
        response.addHeader("Content-Length", "" + data.length);
        response.setContentType("application/octet-stream; charset=UTF-8");

        IOUtils.write(data, response.getOutputStream());
    }

    @RequestMapping("/genTable")
    @AutoEntityProcess(LOG_MSG = "生成表", CUSTOM_EXECUTE_WITHOUT_TRANSACTIONAL = true, AUTO_EXECUTE = false)
    public ResMsg genTable(@RequestParam("generate") boolean generate) throws Exception {
        List<String> sqls = new ArrayList<>();
        List<EntityContainer> entitiesInfo = codeGenService.getEntitiesInfo();
        try {
            entitiesInfo.forEach(entityInfo -> sqls.add(sqlUtil.createSql(entityInfo)));
        } catch (Exception e) {
            throw new JdbcException("sql生成错误：" + e.getMessage());
        }
        if (generate) {
            try {
                sqls.forEach(sql -> sqlService.executeSql(sql));
            } catch (Exception e) {
                if (e.getMessage().contains(" already exists"))
                    throw new JdbcException("表" + "已存在");
                else
                    throw new JdbcException("sql执行错误：" + e.getMessage());
            }
        }
        Map<String, Object> resMap = new HashMap<>();
        resMap.put("sqls", sqls);
        return ResMsg.successRes(resMap);
    }

}
